import hashlib
from django.contrib.auth.models import AbstractUser
from django.db import models
from dvadmin.utils.models import CoreModel, table_prefix

STATUS_CHOICES = (
    (0, "禁用"),
    (1, "启用"),
)


class Users(AbstractUser, CoreModel):
    username = models.CharField(max_length=150, unique=True, db_index=True, verbose_name='用户账号', help_text="用户账号")
    email = models.EmailField(max_length=255, verbose_name="邮箱", null=True, blank=True, help_text="邮箱")
    mobile = models.CharField(max_length=255, verbose_name="电话", null=True, blank=True, help_text="电话")
    # avatar = models.CharField(max_length=255, verbose_name="头像", null=True, blank=True, help_text="头像")
    name = models.CharField(max_length=40, verbose_name="姓名", help_text="姓名")
    GENDER_CHOICES = (
        (0, "女"),
        (1, "男"),
    )
    gender = models.IntegerField(choices=GENDER_CHOICES, default=1, verbose_name="性别", null=True, blank=True,
                                 help_text="性别")
    # post = models.ManyToManyField(to='Post', verbose_name='关联岗位', db_constraint=False, help_text="关联岗位")
    post = models.CharField(max_length=40, null=True, blank=True, verbose_name="职位", help_text="职位")
    role = models.ManyToManyField(to='Role', null=True, blank=True, verbose_name='关联角色', db_constraint=False,
                                  help_text="关联角色", related_name='user_role')
    dept = models.ForeignKey(to='Dept', verbose_name='所属部门', on_delete=models.PROTECT, db_constraint=False, null=True,
                             blank=True, help_text="关联部门")

    def set_password(self, raw_password):
        super().set_password(hashlib.md5(raw_password.encode(encoding='UTF-8')).hexdigest())

    class Meta:
        db_table = table_prefix + "sysuser"
        verbose_name = '用户表'
        verbose_name_plural = verbose_name
        ordering = ('-create_datetime',)


# class Post(CoreModel):
#     name = models.CharField(null=False, max_length=64, verbose_name="岗位名称", help_text="岗位名称")
#     code = models.CharField(max_length=32, verbose_name="岗位编码", help_text="岗位编码")
#     sort = models.IntegerField(default=1, verbose_name="岗位顺序", help_text="岗位顺序")
#     STATUS_CHOICES = (
#         (0, "离职"),
#         (1, "在职"),
#     )
#     status = models.IntegerField(choices=STATUS_CHOICES, default=1, verbose_name="岗位状态", help_text="岗位状态")
#
#     class Meta:
#         db_table = table_prefix + "sys_post"
#         verbose_name = '岗位表'
#         verbose_name_plural = verbose_name
#         ordering = ('sort',)
#

class Role(CoreModel):
    name = models.CharField(max_length=64, verbose_name="角色名称", help_text="角色名称")
    key = models.CharField(max_length=64, unique=True, verbose_name="权限字符", help_text="权限字符")
    sort = models.IntegerField(default=1, verbose_name="角色顺序", help_text="角色顺序")
    status = models.BooleanField(default=True, verbose_name="角色状态", help_text="角色状态")
    admin = models.BooleanField(default=False, verbose_name="是否为admin", help_text="是否为admin")
    DATASCOPE_CHOICES = (
        (0, "仅本人数据权限"),
        (1, "本部门及以下数据权限"),
        (2, "本部门数据权限"),
        (3, "全部数据权限"),
        (4, "自定数据权限"),
    )
    data_range = models.IntegerField(default=0, choices=DATASCOPE_CHOICES, verbose_name="数据权限范围", help_text="数据权限范围")
    remark = models.TextField(verbose_name="备注", help_text="备注", null=True, blank=True)
    dept = models.ManyToManyField(to='Dept', verbose_name='数据权限-关联部门', db_constraint=False, help_text="数据权限-关联部门")

    menu = models.ManyToManyField(to='Menu', verbose_name='关联菜单', db_constraint=False, help_text="关联菜单")
    road = models.ManyToManyField(to='RoadsInfos', verbose_name='关联路线', db_constraint=False, help_text="关联路线")
    structure = models.ManyToManyField(to='Structures', verbose_name='关联构造物', db_constraint=False, help_text="关联构造物")
    device_type = models.ManyToManyField(to='DeviceTypes', verbose_name='关联控制设备类别', db_constraint=False,
                                         help_text="关联控制设备类别")

    # permission = models.ManyToManyField(to='MenuButton', verbose_name='关联菜单的接口按钮', db_constraint=False, help_text="关联菜单的接口按钮")

    class Meta:
        db_table = table_prefix + 'sysrole'
        verbose_name = '角色表'
        verbose_name_plural = verbose_name
        ordering = ('sort',)


class Dept(CoreModel):
    name = models.CharField(max_length=64, null=True, blank=True, verbose_name="部门名称", help_text="部门名称")
    sort = models.IntegerField(default=1, verbose_name="显示排序", help_text="显示排序")
    owner = models.CharField(max_length=32, verbose_name="负责人", null=True, blank=True, help_text="负责人")
    phone = models.CharField(max_length=32, verbose_name="联系电话", null=True, blank=True, help_text="联系电话")
    address = models.CharField(max_length=200, verbose_name="通讯地址", null=True, blank=True, help_text="通讯地址")
    email = models.EmailField(max_length=32, verbose_name="邮箱", null=True, blank=True, help_text="邮箱")
    type = models.ForeignKey(to='SysDict', on_delete=models.CASCADE, default=None, verbose_name="系统类别",
                             db_constraint=False, null=True, blank=True, help_text="系统类别")
    status = models.BooleanField(default=True, verbose_name="部门状态", null=True, blank=True,
                                 help_text="部门状态")
    parent = models.ForeignKey(to='Dept', on_delete=models.CASCADE, default=None, verbose_name="上级部门",
                               db_constraint=False, null=True, blank=True, help_text="上级部门")

    class Meta:
        db_table = table_prefix + "sysdept"
        verbose_name = '部门表'
        verbose_name_plural = verbose_name
        ordering = ('sort',)


# class Button(CoreModel):
#     name = models.CharField(max_length=64,unique=True, verbose_name="权限名称", help_text="权限名称")
#     value = models.CharField(max_length=64,unique=True, verbose_name="权限值", help_text="权限值")
#
#     class Meta:
#         db_table = table_prefix + "sys_button"
#         verbose_name = '权限标识表'
#         verbose_name_plural = verbose_name
#         ordering = ('-name',)
#
#
class Menu(CoreModel):
    parent = models.ForeignKey(to='Menu', on_delete=models.CASCADE, verbose_name="上级菜单", null=True, blank=True,
                               db_constraint=False, help_text="上级菜单")
    icon = models.CharField(max_length=64, verbose_name="菜单图标", null=True, blank=True, help_text="菜单图标")
    name = models.CharField(max_length=64, verbose_name="菜单名称", help_text="菜单名称")
    sort = models.IntegerField(default=1, verbose_name="显示排序", null=True, blank=True, help_text="显示排序")
    # ISLINK_CHOICES = (
    #     (0, "否"),
    #     (1, "是"),
    # )
    # is_link = models.BooleanField(default=False, verbose_name="是否外链", help_text="是否外链")
    is_catalog = models.BooleanField(default=False, verbose_name="是否目录", help_text="是否目录")
    web_path = models.CharField(max_length=128, verbose_name="路由地址", null=True, blank=True, help_text="路由地址")
    # component = models.CharField(max_length=128, verbose_name="组件地址", null=True, blank=True, help_text="组件地址")
    # component_name = models.CharField(max_length=50, verbose_name="组件名称", null=True, blank=True, help_text="组件名称")
    status = models.BooleanField(default=True, blank=True, verbose_name="菜单状态", help_text="菜单状态")
    # cache = models.BooleanField(default=False, blank=True, verbose_name="是否页面缓存", help_text="是否页面缓存")
    visible = models.BooleanField(default=True, blank=True, verbose_name="是否显示", help_text="是否显示")

    class Meta:
        db_table = table_prefix + "sysmenu"
        verbose_name = '菜单表'
        verbose_name_plural = verbose_name
        ordering = ('sort',)


# class MenuButton(CoreModel):
#     menu = models.ForeignKey(to="Menu", db_constraint=False, related_name="menuPermission", on_delete=models.CASCADE,
#                              verbose_name="关联菜单", help_text='关联菜单')
#     name = models.CharField(max_length=64, verbose_name="名称", help_text="名称")
#     value = models.CharField(max_length=64, verbose_name="权限值", help_text="权限值")
#     api = models.CharField(max_length=200, verbose_name="接口地址", help_text="接口地址")
#     METHOD_CHOICES = (
#         (0, "GET"),
#         (1, "POST"),
#         (2, "PUT"),
#         (3, "DELETE"),
#     )
#     method = models.IntegerField(default=0, verbose_name="接口请求方法", null=True, blank=True, help_text="接口请求方法")
#
#     class Meta:
#         db_table = table_prefix + "sys_menu_button"
#         verbose_name = '菜单权限表'
#         verbose_name_plural = verbose_name
#         ordering = ('-name',)


# class Dictionary(CoreModel):
#     code = models.CharField(max_length=100, blank=True, null=True, verbose_name="编码", help_text="编码")
#     label = models.CharField(max_length=100, blank=True, null=True, verbose_name="显示名称", help_text="显示名称")
#     value = models.CharField(max_length=100, blank=True, null=True, verbose_name="实际值", help_text="实际值")
#     parent = models.ForeignKey(to='self', related_name='sublist', db_constraint=False, on_delete=models.PROTECT,
#                                blank=True, null=True,
#                                verbose_name="父级", help_text="父级")
#     status = models.BooleanField(default=True,blank=True, verbose_name="状态", help_text="状态")
#     sort = models.IntegerField(default=1, verbose_name="显示排序", null=True, blank=True, help_text="显示排序")
#     remark = models.CharField(max_length=2000, blank=True, null=True, verbose_name="备注", help_text="备注")
#
#     class Meta:
#         db_table = table_prefix + 'dict'
#         verbose_name = "字典表"
#         verbose_name_plural = verbose_name
#         ordering = ('sort',)


class OperationLog(CoreModel):
    request_modular = models.CharField(max_length=64, verbose_name="请求模块", null=True, blank=True, help_text="请求模块")
    request_path = models.CharField(max_length=400, verbose_name="请求地址", null=True, blank=True, help_text="请求地址")
    request_body = models.TextField(verbose_name="请求参数", null=True, blank=True, help_text="请求参数")
    request_method = models.CharField(max_length=8, verbose_name="请求方式", null=True, blank=True, help_text="请求方式")
    request_msg = models.TextField(verbose_name="操作说明", null=True, blank=True, help_text="操作说明")
    request_ip = models.CharField(max_length=32, verbose_name="请求ip地址", null=True, blank=True, help_text="请求ip地址")
    request_browser = models.CharField(max_length=64, verbose_name="请求浏览器", null=True, blank=True, help_text="请求浏览器")
    response_code = models.CharField(max_length=32, verbose_name="响应状态码", null=True, blank=True, help_text="响应状态码")
    request_os = models.CharField(max_length=64, verbose_name="操作系统", null=True, blank=True, help_text="操作系统")
    json_result = models.TextField(verbose_name="返回信息", null=True, blank=True, help_text="返回信息")
    status = models.BooleanField(default=False, verbose_name="响应状态", help_text="响应状态")

    class Meta:
        db_table = table_prefix + 'sysoperationlog'
        verbose_name = '操作日志'
        verbose_name_plural = verbose_name
        ordering = ('-create_datetime',)


# def media_img_name(instance, filename):
#     h = instance.md5sum
#     basename, ext = os.path.splitext(filename)
#     return os.path.join('media/imgs', h[0:1], h[1:2], h + ext.lower())
#
#
# class ImgList(CoreModel):
#     name = models.CharField(max_length=50, null=True, blank=True, verbose_name="名称", help_text="名称")
#     url = models.ImageField(upload_to=media_img_name)
#     md5sum = models.CharField(max_length=36, blank=True, verbose_name="文件md5", help_text="文件md5")
#
#     def save(self, *args, **kwargs):
#         if not self.md5sum:  # file is new
#             md5 = hashlib.md5()
#             for chunk in self.url.chunks():
#                 md5.update(chunk)
#             self.md5sum = md5.hexdigest()
#         super(ImgList, self).save(*args, **kwargs)
#
#     class Meta:
#         db_table = table_prefix + 'img_list'
#         verbose_name = '图片管理'
#         verbose_name_plural = verbose_name
#         ordering = ('-create_datetime',)
#
#
# def media_file_name(instance, filename):
#     h = instance.md5sum
#     basename, ext = os.path.splitext(filename)
#     return os.path.join('media/files', h[0:1], h[1:2], h + ext.lower())
#
#
# class FileList(CoreModel):
#     name = models.CharField(max_length=50, null=True, blank=True, verbose_name="名称", help_text="名称")
#     url = models.FileField(upload_to=media_file_name)
#     md5sum = models.CharField(max_length=36, blank=True, verbose_name="文件md5", help_text="文件md5")
#
#     def save(self, *args, **kwargs):
#         if not self.md5sum:  # file is new
#             md5 = hashlib.md5()
#             for chunk in self.url.chunks():
#                 md5.update(chunk)
#             self.md5sum = md5.hexdigest()
#         super(FileList, self).save(*args, **kwargs)
#
#     class Meta:
#         db_table = table_prefix + 'file_list'
#         verbose_name = '文件管理'
#         verbose_name_plural = verbose_name
#         ordering = ('-create_datetime',)
#
#
# class Area(CoreModel):
#     name = models.CharField(max_length=100, verbose_name="名称", help_text="名称")
#     code = models.CharField(max_length=20, verbose_name="地区编码", help_text="地区编码", unique=True, db_index=True)
#     level = models.BigIntegerField(verbose_name="地区层级(1省份 2城市 3区县 4乡级)", help_text="地区层级(1省份 2城市 3区县 4乡级)")
#     pinyin = models.CharField(max_length=255, verbose_name="拼音", help_text="拼音")
#     initials = models.CharField(max_length=20, verbose_name="首字母", help_text="首字母")
#     enable = models.BooleanField(default=True, verbose_name="是否启用", help_text="是否启用")
#     pcode = models.ForeignKey(to='self', verbose_name='父地区编码', to_field="code", on_delete=models.CASCADE,
#                               db_constraint=False, null=True, blank=True, help_text="父地区编码")
#
#     class Meta:
#         db_table = table_prefix + "area"
#         verbose_name = '地区表'
#         verbose_name_plural = verbose_name
#         ordering = ('code',)
#
#     def __str__(self):
#         return f"{self.name}"
#

class ApiWhiteList(CoreModel):
    url = models.CharField(max_length=200, help_text="url地址", verbose_name="url")
    METHOD_CHOICES = (
        (0, "GET"),
        (1, "POST"),
        (2, "PUT"),
        (3, "DELETE"),
    )
    method = models.IntegerField(default=0, verbose_name="接口请求方法", null=True, blank=True, help_text="接口请求方法")

    class Meta:
        db_table = table_prefix + "apiwhitelist"
        verbose_name = '接口白名单'
        verbose_name_plural = verbose_name
        ordering = ('-create_datetime',)


class SysLog(CoreModel):
    info = models.CharField(max_length=255, blank=True, null=True, verbose_name="日志信息", help_text="日志信息")
    memo = models.TextField(blank=True, null=True, verbose_name="备注", help_text="备注")
    type = models.ForeignKey(to='SysDict', verbose_name='日志类别', on_delete=models.CASCADE,
                             db_constraint=False, null=True, blank=True, help_text="日志类别")
    logtime = models.DateTimeField(auto_now_add=True, null=True, blank=True, help_text="日志时间",
                                   verbose_name="日志时间")

    class Meta:
        db_table = table_prefix + 'syslog'
        verbose_name = "系统日志"
        verbose_name_plural = verbose_name
        ordering = ('-logtime',)


class SysDict(CoreModel):
    name = models.CharField(max_length=10, blank=True, null=True, verbose_name="名称", help_text="名称")
    value = models.CharField(max_length=255, blank=True, null=True, verbose_name="值", help_text="值")
    up = models.ForeignKey(to='self', related_name='sublist', db_constraint=False, on_delete=models.PROTECT,
                           blank=True, null=True, verbose_name="父级", help_text="父级")
    status = models.BooleanField(default=True, null=True, blank=True, verbose_name="状态", help_text="状态")
    sort = models.IntegerField(default=1, verbose_name="显示排序", null=True, blank=True, help_text="显示排序")
    memo = models.CharField(max_length=255, blank=True, null=True, verbose_name="备注", help_text="备注")

    class Meta:
        db_table = table_prefix + 'sysdic'
        verbose_name = "字典表"
        verbose_name_plural = verbose_name
        ordering = ('sort',)


class SysTypes(CoreModel):
    ename = models.CharField(max_length=50, blank=True, null=True, verbose_name="英文名称", help_text="英文名称")
    cname = models.CharField(max_length=50, blank=True, null=True, verbose_name="中文名称", help_text="中文名称")

    class Meta:
        db_table = table_prefix + 'systypes'
        verbose_name = "系统类别表"
        verbose_name_plural = verbose_name
        ordering = ('-create_datetime',)


class DeviceTypes(CoreModel):
    ename = models.CharField(max_length=50, blank=True, null=True, verbose_name="英文名称", help_text="英文名称")
    cname = models.CharField(max_length=50, blank=True, null=True, verbose_name="中文名称", help_text="中文名称")
    systype = models.ForeignKey(to='SysTypes', verbose_name='系统类别', on_delete=models.CASCADE,
                                db_constraint=False, null=True, blank=True, help_text="系统类别")

    class Meta:
        db_table = table_prefix + 'devicetypes'
        verbose_name = "设备类别表"
        verbose_name_plural = verbose_name
        ordering = ('-create_datetime',)


class Department(CoreModel):
    name = models.CharField(max_length=100, verbose_name="全称", help_text="全称", null=True, blank=True)
    phone = models.CharField(max_length=18, verbose_name="联系电话", help_text="联系电话", null=True, blank=True)
    simplename = models.CharField(max_length=20, verbose_name="简称", help_text="简称", null=True, blank=True)
    type = models.IntegerField(verbose_name="单位类别", help_text="单位类别", null=True, blank=True)

    class Meta:
        db_table = table_prefix + 'department'
        verbose_name = "厂商表"
        verbose_name_plural = verbose_name


class RoadsInfos(CoreModel):
    ename = models.CharField(max_length=10, verbose_name="英文名称", help_text="英文名称", null=True, blank=True)
    cname = models.CharField(max_length=50, verbose_name="中文名称", help_text="中文名称", null=True, blank=True)
    roadtype = models.ForeignKey(SysDict, db_column='roadtype', on_delete=models.RESTRICT, verbose_name="道路等级",
                                 help_text="道路等级", null=True, blank=True)
    upid = models.ForeignKey('self', db_column='upid', on_delete=models.RESTRICT, verbose_name="父ID", help_text="父ID",
                             null=True, blank=True)
    manunit = models.ForeignKey(Department, db_column='manunit', on_delete=models.RESTRICT, verbose_name="管养单位",
                                help_text="管养单位", null=True, blank=True)
    roadwidth = models.FloatField(verbose_name="道路总宽度", help_text="道路总宽度", null=True, blank=True)
    roadweight = models.IntegerField(verbose_name="道路总车道数", help_text="道路总车道数", null=True, blank=True)
    roadlength = models.FloatField(verbose_name="道路长度", help_text="道路长度", null=True, blank=True)
    hademergency = models.BooleanField(verbose_name="是否有应急车道", help_text="是否有应急车道", null=True, blank=True)
    roadtraffic = models.BooleanField(verbose_name="道路是否双通", help_text="道路是否双通", null=True, blank=True)
    lstartplno = models.CharField(max_length=20, verbose_name="左起始点", help_text="左起始点", null=True, blank=True)
    lendplno = models.CharField(max_length=20, verbose_name="左终止点", help_text="左终止点", null=True, blank=True)
    direct = models.CharField(max_length=50, verbose_name="路段方向", help_text="路段方向", null=True, blank=True)
    roadcode = models.CharField(max_length=20, verbose_name="道路编号", help_text="道路编号", null=True, blank=True)
    lane = models.IntegerField(verbose_name="车道数", help_text="车道数", null=True, blank=True)
    rstartplno = models.CharField(max_length=20, verbose_name="右起始点", help_text="右起始点", null=True, blank=True)
    rendplno = models.CharField(max_length=20, verbose_name="右终止点", help_text="右终止点", null=True, blank=True)
    pointname1 = models.CharField(max_length=50, verbose_name="路段连接城市名1", help_text="路段连接城市名1", null=True, blank=True)
    pointname2 = models.CharField(max_length=50, verbose_name="路段连接城市名2", help_text="路段连接城市名2", null=True, blank=True)
    # startplno = models.CharField(max_length=200, verbose_name="开始桩号", help_text="开始桩号", null=True, blank=True)
    # endplno = models.CharField(max_length=200, verbose_name="结束桩号", help_text="结束桩号", null=True, blank=True)
    geoservice = models.CharField(max_length=200, verbose_name="gis服务地址", help_text="gis服务地址", null=True, blank=True)

    class Meta:
        db_table = table_prefix + 'roadsinfos'
        verbose_name = "道路（路段）信息表"
        verbose_name_plural = verbose_name


class Structures(CoreModel):
    roadid = models.ForeignKey(RoadsInfos, db_column='roadid', on_delete=models.RESTRICT, verbose_name="路段ID",
                               help_text="路段ID", null=True, blank=True)
    structtype = models.IntegerField(verbose_name="结构类别", help_text="结构类别", null=True, blank=True)
    sname = models.CharField(max_length=50, verbose_name="结构名称", help_text="结构名称", null=True, blank=True)
    lstartplno = models.CharField(max_length=20, verbose_name="左线开始桩号", help_text="左线开始桩号", null=True, blank=True)
    lendplno = models.CharField(max_length=20, verbose_name="左线结束桩号", help_text="左线结束桩号", null=True, blank=True)
    centerplno = models.CharField(max_length=20, verbose_name="GIS中心点", help_text="GIS中心点", null=True, blank=True)
    manunit = models.ForeignKey(Department, db_column='manunit', on_delete=models.RESTRICT, verbose_name="管养机构",
                                help_text="管养机构", null=True, blank=True)
    rstartplno = models.CharField(max_length=20, verbose_name="右线开始桩号", help_text="右线开始桩号", null=True, blank=True)
    rendplno = models.CharField(max_length=20, verbose_name="右线结束桩号", help_text="右线结束桩号", null=True, blank=True)
    upid = models.IntegerField(verbose_name="父构造物ID", help_text="父构造物ID", null=True, blank=True)
    lat = models.FloatField(verbose_name="纬度", help_text="纬度", null=True, blank=True)
    lon = models.FloatField(verbose_name="经度", help_text="经度", null=True, blank=True)

    class Meta:
        db_table = table_prefix + 'structures'
        verbose_name = "结构信息"
        verbose_name_plural = verbose_name


class PersionInfo(models.Model):
    name = models.CharField(max_length=50, verbose_name='人员名称', help_text="人员名称", null=True, blank=True)
    phone = models.CharField(max_length=11, verbose_name="联系电话", help_text="联系电话", null=True, blank=True)
    position = models.CharField(max_length=20, verbose_name='人员职位', help_text="人员职位", null=True, blank=True)
    company = models.ForeignKey(Department, db_column='company', on_delete=models.CASCADE, verbose_name="厂商信息", help_text="厂商信息", null=True, blank=True)
    user = models.ForeignKey(Users, db_column='userid', on_delete=models.CASCADE, verbose_name="系统用户id", help_text="系统用户id", null=True, blank=True)
    perstiontype = models.IntegerField(default=0, verbose_name='人员类别', help_text="人员类别", null=True, blank=True)

    class Meta:
        db_table = table_prefix + 'persioninfo'
        verbose_name = "外部人员表"
        verbose_name_plural = verbose_name
